package cn.tedu.charging.cost.service.impl;

import cn.tedu.charging.common.pojo.param.ChargingProcessParam;
import cn.tedu.charging.common.pojo.vo.ChargingProcessVO;
import cn.tedu.charging.cost.dao.repository.CostRepository;
import cn.tedu.charging.cost.pojo.po.CostRulePO;
import cn.tedu.charging.cost.service.CostService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Slf4j
@Service
public class CostServiceImpl implements CostService {

    @Autowired
    private CostRepository costRepository;

    @Override
    public ChargingProcessVO calculate(ChargingProcessParam chargingProcessParam) {

        Integer currentHour = getCurrentHour();
        log.debug("获取当前时间小时数:{}",currentHour);
        Integer gunType = chargingProcessParam.getGunType();
        Integer stationId = chargingProcessParam.getStationId();
        CostRulePO costRulePO = getMatchCostRuleByGunTypeAndTime(
                stationId,
                gunType,
                currentHour);
        log.debug("通过场站id:{},枪类型:{},时间:{},匹配到计价规则:{}",
                stationId,gunType,currentHour,costRulePO);

        if (costRulePO != null) {
            String name = costRulePO.getName();
            //获取到匹配的计价规则的每度电的价格
            BigDecimal powerFee = costRulePO.getPowerFee();
            //获取设备同步的充电度数
            Float chargingCapacity = chargingProcessParam.getChargingCapacity();
            BigDecimal cost = getCost(chargingCapacity, powerFee);
            log.debug("当前时间:{},计价规则的名称:{}," +
                            "充电度数:{},电费的单价:{}," +
                            "本次花费:{},总花费:{}",
                    currentHour,name,
                    chargingCapacity,powerFee,
                    cost,cost);
        }else {
            log.error("故障，计价规则为空，进行系统告警，业务停止");
        }

        ChargingProcessVO chargingProcessVO = new ChargingProcessVO();
        chargingProcessVO.setOrderNo(chargingProcessParam.getOrderNo());
        chargingProcessVO.setGunId(chargingProcessParam.getGunId());
        return chargingProcessVO;
    }

    /**
     * 计算价格
     * @param chargingCapacity
     * @param powerFee
     * @return
     */
    private BigDecimal getCost(Float chargingCapacity,BigDecimal powerFee) {
        //1>通过构造器 进行类型转换
        //Float 转换为 BigDecimal
        //BigDecimal bigDecimal = new BigDecimal(chargingCapacity);
        //基本类型的数字转换为 包装类型的 Integer
        //Integer i = new Integer(1);
        //String 转换为 包装类型的 String
        //String s = new String("1");

        //2>通过方法 进行类型转换 valueOf
        //通过方法 valueOf 转换 float 转为 String
        //String s = String.valueOf(chargingCapacity);
        //Float 转换为 BigDecimal
        BigDecimal bigDecimal = BigDecimal.valueOf(chargingCapacity);
        //BigDecimal add 加计算  multiply 乘法
        return bigDecimal.multiply(powerFee);
    }

    /**
     * 获取当前时间的小时
     * @return
     */
    private Integer getCurrentHour(){
        //@Deprecated
        // Date date = new Date();
        //date.getDate()
        //joda-time 时间的库
        //LocalDateTime java.time
        LocalDateTime localDateTime = LocalDateTime.now();
        return localDateTime.getHour();
    }


    private CostRulePO getMatchCostRuleByGunTypeAndTime(Integer stationId,
                                                        Integer gunType,
                                                        Integer hour) {
        log.debug("通过场站id获取计价规则列表-入参:{}",stationId);
        List<CostRulePO> costRulePOS = getCostRuleByStationId(stationId);
        log.debug("通过场站id获取计价规则列表-入参:{},出参:{}",stationId,costRulePOS);

        if (!CollectionUtils.isEmpty(costRulePOS)) {


            /*costRulePOS.forEach(costRulePO -> {
                //具体的匹配逻辑
            });*/

      /*      Optional<CostRulePO> first = costRulePOS.stream().filter(costRulePO ->
                    costRulePO.getGunType().equals(gunType)
                            && hour >= costRulePO.getStartTime()
                            && hour < costRulePO.getEndTime()
            ).findFirst();
            if (first.isPresent()) { //return value != null;
                return first.get();
            }
*/



            for (CostRulePO costRulePO : costRulePOS) {
                //获取计价规则的枪类型
                Integer costRuleGunType = costRulePO.getGunType();
                //判断入参的枪类型和计价规则的枪类型是否一致
                if (costRuleGunType.equals(gunType)){
                    //获取计价规则开始时间
                    Integer startTime = costRulePO.getStartTime();
                    //获取计价规则结束时间
                    Integer endTime = costRulePO.getEndTime();
                    /**
                     * 当前时间 17:04   获取到小时数 17
                     * 找到真实的计价规则 通过人肉的方式 去判断 当前时间属于哪个时间段
                     * 8,12
                     * 14,18
                     * 18,24
                     * 12,14
                     * 0,8
                     *
                     * 17在 14 和 18 之间
                     * 17 > 14 并且 17 < 18
                     * hour > startTime && hour < endTime
                     *
                     * 边界值
                     * 如果当前时间是 8 改如何处理
                     * 如果当前时间是 12 改如何处理
                     *
                     * 如果当前时间是 8  是 大于 还是 大于等于
                     * 如果当前时间是 12  是 小于 还是 小于于等于
                     * 左闭右开
                     * 左开右闭
                     */
                    if (hour >= startTime && hour < endTime) {
                        return costRulePO;
                    }
                }
            }
        }
        //循环完了，还没有找到匹配的，返回null，表示没有匹配到计价规则
        return null;
    }

    /**
     * 通过场站id查询 当前场站所有的计价规则
     * @param stationId
     * @return
     */
    private List<CostRulePO> getCostRuleByStationId(Integer stationId) {
        return costRepository.getCostRulesByStationId(stationId);
    }
}
